#!/usr/bin/env python
import sys, os
from string import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from glew import *

# Checks for GL posted errors after appropriate calls
def printOpenGLError():
   err = glGetError()
   if (err != GL_NO_ERROR):
	  print 'GLERROR: ', gluErrorString(err)
#	  sys.exit()

class SimpleShader():
    def __init__(self, file):
        self.filename = file
    def loadShaders(self):
        glewInit()
        vertfile = self.filename + '.vert'
        fragfile = self.filename + '.frag'      
        self.vertstr = open(vertfile, 'r').read()
        self.fragString = open(fragfile, 'r').read()
        
        print 'glCreateProgramObjectARB'
        self.shaderProgram = glCreateProgramObjectARB()
        printOpenGLError()

        if(len(vertfile) != 0):
            print 'glCreateShaderObjectARB'
            vertShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)
            printOpenGLError()
    
            print 'glShaderSourceARB'
            glShaderSourceARB(vertShader, 1, [self.vertstr])
            printOpenGLError()
       
            print 'glCompileShaderARB'
            glCompileShaderARB(vertShader)
            success = glGetObjectParameterivARB(vertShader, GL_OBJECT_COMPILE_STATUS_ARB)
            if (not success):
                print glGetInfoLogARB(vertShader)
                sys.exit()
         
            print 'glAttachObjectARB'
            glAttachObjectARB(self.shaderProgram, vertShader)
            printOpenGLError()
      
        if(len(fragfile) != 0):
            print 'glCreateShaderObjectARB'
            fragShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)
            printOpenGLError()
    
            print 'glShaderSourceARB'
            glShaderSourceARB(fragShader, 1, [self.fragString])
            printOpenGLError()
    
            print 'glCompileShaderARB'
            glCompileShaderARB(fragShader)
            success = glGetObjectParameterivARB(fragShader, GL_OBJECT_COMPILE_STATUS_ARB)
            if (not success):
                print glGetInfoLogARB(fragShader)
                sys.exit()
    
            print 'glAttachObjectARB'
            glAttachObjectARB(self.shaderProgram, fragShader)
            printOpenGLError()
    
        print 'glLinkProgramARB'
        glLinkProgramARB(self.shaderProgram)
        printOpenGLError()
        success = glGetObjectParameterivARB(self.shaderProgram, GL_OBJECT_LINK_STATUS_ARB)
        if (not success):
            print glGetInfoLogARB(self.shaderProgram)
            sys.exit()
    
        print 'glUseProgramObjectARB'
        glUseProgramObjectARB(self.shaderProgram)
        printOpenGLError()
          
    def setUniform(self, name, val):
        self.bind()
        if isinstance(val[0], float):
	        if(len(val) == 1):
	            glUniform1fARB(glGetUniformLocationARB(self.shaderProgram, name), val[0])
	        elif(len(val) == 2):
	            glUniform2fvARB(glGetUniformLocationARB(self.shaderProgram, name), 1, val)
	        elif(len(val) == 3):
	            glUniform3fvARB(glGetUniformLocationARB(self.shaderProgram, name), 1, val)
	        elif(len(val) == 4):
	            glUniform4fvARB(glGetUniformLocationARB(self.shaderProgram, name), 1, val)
        if isinstance(val[0], int):
            if(len(val) == 1):
                glUniform1iARB(glGetUniformLocationARB(self.shaderProgram, name), val[0])
            elif(len(val) == 2):
                glUniform2ivARB(glGetUniformLocationARB(self.shaderProgram, name), 1, val)
            elif(len(val) == 3):
                glUniform3ivARB(glGetUniformLocationARB(self.shaderProgram, name), 1, val)
            elif(len(val) == 4):
                glUniform4ivARB(glGetUniformLocationARB(self.shaderProgram, name), 1, val)
        printOpenGLError()

    def bind(self):
        glUseProgramObjectARB(self.shaderProgram)
    def unbind(self):
        glUseProgramObjectARB(0)

